# 证据工程与面试追问

这一章解释为什么项目不止是一条提示词，以及怎样准确描述已经实现的工程能力。

## 一次运行留下什么

成功运行会在 `artifacts/<run_id>/` 中保存四个文件。

| 文件 | 内容 | 解决的问题 |
| --- | --- | --- |
| evidence.json | 请求、来源、SQL 尝试、模型记录、核验结果、贡献与轨迹 | 这次分析具体经历了什么 |
| query.sql | 最后通过的 SQL | 数据怎样查询出来 |
| parameters.json | 两月边界和地区 | SQL 的时间与范围是什么 |
| report.html | 确定性数字与图表 | 人怎样阅读计算结果 |

`provenance` 记录数据库 SHA256、模拟数据元信息、业务 Python 文件指纹、官方提交、DB-GPT 和 Python 版本、生成时间。SHA256 相同可以帮助确认比较的是同一份文件内容；它不能单独证明数据库真实可信，也不是备份。

当前下载包不包含数据库快照，来源信息也没有完整记录官方未提交补丁指纹和全部依赖锁文件指纹。因此准确说法是“保留复算依据并支持同一可用数据快照下复算”，不应说“仅靠 ZIP 就能在任何机器上完整重建所有环境”。

失败流程也尽量保存 evidence，保留哪个 SQL 被拒绝以及原因。不过初始化在 try 之前发生的故障、磁盘写入失败等不保证成功落盘；当前保存也不是完整的原子提交机制。这些是后续工程增强空间。

## 如何复算和学习

在项目目录使用下面的 PowerShell 命令可以运行无需模型的标准基线。它会新增一个运行证据目录，不修改既有模拟库。

```powershell
.\.venv\Scripts\python.exe -m commerce.cli --mode reference --as-of 2026-09-16 --region 华东
```

然后将输出的运行编号替换到下面的路径：

```powershell
.\.venv\Scripts\python.exe -m commerce.cli --replay artifacts/你的运行编号/evidence.json
```

replay 先比较当前基础数据库指纹，再重新执行已保存的 SQL、核对保存的独立基准，最后重新计算贡献并比较完整分析结果。它不调用模型重新生成 SQL；复算关心的是既定查询和既定数据能否重现数字。

注意 CLI 当前固定使用基础 `data/commerce.sqlite`，不会自动根据官方证据中的 `database_path` 选择副本。官方副本与基础文件一致时可以核验，二者变化后可能因为指纹不同而拒绝。不要为了让复算通过而删除这个检查。

阅读 evidence 时，建议按 `request → params → sql_attempts → independent_reference → analysis.totals → analysis.permutations → analysis.factors → provenance` 的顺序。先明确问题与口径，再看数字，最后确认来源。

## 官方接入中真正解决的两个问题

第一，工具已注册，不代表模型知道工具存在。当前官方定制工作流中，业务工具进入执行工具包，但描述没有进入对应提示词。补丁把业务工具描述补进 prompt，并提示适用时优先使用已核验工具。这个问题体现了“可执行”与“可发现”是两件事。

第二，间接工具执行器使用旧模块路径导入资源 API，导致工具调度失败。补丁改为当前模块位置。业务代码正确也可能因为框架调用桥断开而失败，所以需要桥接层测试。

两处改动保存在 `official-patches/registered-business-tools.patch`。它们分别对应官方 `agentic_data_api.py` 和 `tools/execute_tool.py`。不能把当前 vendor 描述为完全无修改，也不应把这两处修复扩大为“重写官方 Agent 架构”。

工具描述里的“优先调用”只是对模型的指令，不是硬路由。官方通用工具仍属于更大的工具系统；专用工具里的 SQLite 限制也不会自动施加到全部通用工具上。若未来要求所有经营查询必须经过核验，应在路由和工具授权层做强制约束。

## 为什么报告使用文件交付

数据库查对、贡献算对之后，模型如果再重新编写报告 HTML，仍可能抄错数或写错单位。曾出现渠道客单价在改写报告时失真的情况。因此工具直接返回实际报告绝对路径，要求 `html_interpreter(file_path=...)` 加载已生成文件。

这降低了重新生成表格数字的风险，但不等于外层模型所有总结都得到形式化保证。验证事实时应以保存的报告和 evidence 为准。更强的实现可以让平台直接渲染报告链接，而不再让模型决定如何展示。

## 测试分别证明什么

已有记录中，27 项业务测试覆盖已知总额、日期边界、跨月退款、拒绝查询、重复连接、缺失渠道、分解加总、模型修复与失败、AWEL 和产物等；2 项官方桥接测试覆盖间接工具调用和原 HTML 文件内容保持。

真实界面链路也已有一次最终成功验证记录，运行编号为 `c8721115df704349a4b89febde64a859`，显示净收入下降 99,000 元。以上是指定用例的验证证据，不能换算成“模型准确率 100%”，也没有证明高并发或生产稳定性。

历史 `VALIDATION.md` 保留前期独立页面状态。阅读时以“最终交付”段为当前集成状态；“未部署官方完整后台”等描述位于明确标注的历史阶段。

## 常见追问与可直接使用的回答

### 既然有 Python 标准答案 为什么还要模型

当前窄场景确实可以直接用标准 SQL 完成业务计算。保留模型是为了复现并评估“自然语言到查询”的真实链路，同时用独立程序展示如何防止错误结果流入报告。它是一个可核验的 Agent 工程样例，不应为使用模型而声称固定报表非得由模型生成。扩展成开放分析平台时，不能为任意问题无限手写一个 oracle，需要受治理指标层、语义模型和分级验证。

### 为什么用 Agent 加工作流

Agent 适合在对话中选择动作，固定工作流适合保证关键步骤不会被随意省略。本项目把灵活性放在外层，把口径、核验和计算放在内层。代价是内层支持范围明确受限，新问题要增加正式契约。

### SQL 合法为什么仍会出错

合法只说明语法和权限允许。例如按创建月份统计收入是合法 SQL，但与支付月份口径不一致。一单多明细的 JOIN 也可以合法执行，却把金额翻倍。结果核验要独立于执行权限检查。

### Shapley 有什么用 为什么不直接相减

相减可以知道总变化，但分给订单量、结构、价格时出现交互项。不同替换顺序会给出不同分账。当前只有三个乘法因素，全部六种顺序成本很低，直接求平均可以给出清晰且可复算的分配规则。

### 数据库指纹能保证什么

它帮助发现本次分析期间文件内容改变，并在复算时识别是否同一文件。它不是事务快照机制，不能解决所有并发一致性问题。当前模拟数据基本静态；生产场景更适合明确的数据版本或只读事务快照。

### 当前有并发控制吗

旧独立 FastAPI 分析接口有容量为 2 的信号量，但官方注册业务工具没有复用这个限制。不能把旧接口的控制宣传成官方全链路全局限流。面向多用户时应在工具入口加入统一并发、超时、取消和任务队列设计。

### 哪些能力还没实现

当前没有任意企业指标理解、完整租户权限体系、生产数据库快照管理、业务因果识别或海量数据验证；官方知识库的 embedding 也尚未配置。多源与知识库是框架可扩展方向，不是本例已经逐项验证的能力。

## 怎样继续扩展才不破坏逻辑

如果增加按商品分析，先决定一笔订单多商品时收入和退款如何分摊，再增加商品粒度的数据契约和独立基准，最后扩展 SQL 生成与展示。不能只 JOIN 商品表后对订单金额求和。

如果支持任意月份，先更换覆盖期充分的数据并保留时间边界检查，再开放明确的开始与结束参数；如果支持真实企业数据，先确认支付、取消、退款等状态和地区快照的定义，再迁移执行器和指标层。

如果要做因果解释，需要补充实验或可支持识别的观测设计。增加一段“请解释原因”的提示词，只会增加叙述，不会自动增加证据。

## 自测是否真的理解

尝试不看文档回答：为什么退款不能只连接本月支付的订单？为什么 COUNT DISTINCT 救不了订单金额？六种顺序中订单量贡献为什么有时是 −50,000，有时是 −39,750？为什么总体客单价不能作为第五项贡献？为什么一次复算不需要模型？

能把这五个问题讲清楚，再按一次完整请求说明各文件职责，就已经掌握了这个项目最关键的逻辑。
